package com.zhouyu;

import com.zhouyu.service.A;
import com.zhouyu.service.B;
import com.zhouyu.tool.MessageBean;
import com.zhouyu.tool.StringToUserPropertyEditor;
import com.zhouyu.service.User;
import com.zhouyu.service.UserService;
import com.zhouyu.tool.StringToUserConverter;
import org.springframework.beans.SimpleTypeConverter;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.OrderComparator;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * https://www.yuque.com/books/share/5f19528d-d89b-4b69-a7bd-9f436a2dd734/pldhnd
 */
public class Test03 {
	public static void main(String[] args) throws IOException {
		/**
		 * AnnotatedBeanDefinitionReader
		 */
		/*AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
		AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(context);
		// 将User.class解析为BeanDefinition
		annotatedBeanDefinitionReader.register(UserService.class);
		System.out.println(context.getBean("userService"));*/


		/**
		 * XmlBeanDefinitionReader
		 */
		/*AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
		XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(context);
		int i = xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml");

		System.out.println(context.getBean("user"));
		System.out.println(i);*/

		/**
		 * ClassPathBeanDefinitionScanner
		 */
		/*AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		context.refresh();
		ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
		scanner.scan("com.zhouyu");
		System.out.println(context.getBean("userService"));*/

		/**
		 * DefaultListableBeanFactory
		 */
		/*DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
		AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
		beanDefinition.setBeanClass(User.class);
		beanFactory.registerBeanDefinition("user", beanDefinition);
		System.out.println(beanFactory.getBean("user"));*/

		/**
		 * 国际化 MessageSource
		 */
		/*AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
		MessageBean messageBean = (MessageBean) context.getBean("messageBean");
		messageBean.test();*/

		/**
		 * Resource 资源加载
		 */
		/*AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
		Resource resource = context.getResource("file:///Users/ade/Documents/crossde/spring-framework-5.3.10/tuling/src/main/java/com/zhouyu/Test.java");
		System.out.println(resource.contentLength());
		System.out.println(resource.getFilename());

		Resource resource1 = context.getResource("https://www.baidu.com");
		System.out.println(resource1.contentLength());
		System.out.println(resource1.getURL());

		Resource resource2 = context.getResource("classpath:spring.xml");
		System.out.println(resource2.contentLength());
		System.out.println(resource2.getURL());
		Resource[] resources = context.getResources("classpath:com/zhouyu/*.class");
		for (Resource resource : resources) {
			System.out.println(resource.contentLength());
			System.out.println(resource.getFilename());
		}*/

		/**
		 * systemEnvironment
		 * systemProperties
		 * propertySources
		 */
		/*AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

		Map<String, Object> systemEnvironment = context.getEnvironment().getSystemEnvironment();
		System.out.println(systemEnvironment);

		System.out.println("=======");

		Map<String, Object> systemProperties = context.getEnvironment().getSystemProperties();
		System.out.println(systemProperties);

		System.out.println("=======");

		MutablePropertySources propertySources = context.getEnvironment().getPropertySources();
		System.out.println(propertySources);

		System.out.println("=======");

		System.out.println(context.getEnvironment().getProperty("NO_PROXY"));
		System.out.println(context.getEnvironment().getProperty("sun.jnu.encoding"));
		System.out.println(context.getEnvironment().getProperty("zhouyu"));*/

		/**
		 * PayloadApplicationEvent
		 */
		/*AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
		context.publishEvent("kkk");*/

		/**
		 * PropertyEditor
		 */
		/*AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
		UserService userService = (UserService) context.getBean("userService");
		userService.test();

//		StringToUserPropertyEditor userPropertyEditor = new StringToUserPropertyEditor();
//		userPropertyEditor.setAsText("123");
//		User user = (User) userPropertyEditor.getValue();
//		System.out.println(user.getName());*/


		/**
		 * ConversionService
		 */
		/*AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
		UserService userService = (UserService) context.getBean("userService");
		userService.test();
//		DefaultConversionService conversionService = new DefaultConversionService();
//		conversionService.addConverter(new StringToUserConverter());
//		User value = conversionService.convert("1", User.class);
//		System.out.println(value);*/


		/**
		 * TypeConverter
		 */
		/*DefaultConversionService conversionService = new DefaultConversionService();
		conversionService.addConverter(new StringToUserConverter());
		SimpleTypeConverter typeConverter = new SimpleTypeConverter();
//		typeConverter.registerCustomEditor(User.class, new StringToUserPropertyEditor());
		typeConverter.setConversionService(conversionService);
		User value = typeConverter.convertIfNecessary("1", User.class);
		System.out.println(value.getName());*/

		/**
		 * OrderComparator
		 * AnnotationAwareOrderComparator
		 */
		/*A a = new A(); // order=3
		B b = new B(); // order=2

		OrderComparator comparator = new OrderComparator();
		System.out.println(comparator.compare(a, b));  // 1

		List list = new ArrayList<>();
		list.add(a);
		list.add(b);

		// 按order值升序排序
		list.sort(comparator);

		System.out.println(list);  // B，A*/
		/*A a = new A(); // order=3
		B b = new B(); // order=2

		AnnotationAwareOrderComparator comparator = new AnnotationAwareOrderComparator();
		System.out.println(comparator.compare(a, b)); // 1

		List list = new ArrayList<>();
		list.add(a);
		list.add(b);

		// 按order值升序排序
		list.sort(comparator);

		System.out.println(list); // B，A*/


		/**
		 * MetadataReader、ClassMetadata、AnnotationMetadata
		 */
		/*SimpleMetadataReaderFactory simpleMetadataReaderFactory = new SimpleMetadataReaderFactory();
		// 构造一个MetadataReader
		MetadataReader metadataReader = simpleMetadataReaderFactory.getMetadataReader("com.zhouyu.service.UserService");
		// 得到一个ClassMetadata，并获取了类名
		ClassMetadata classMetadata = metadataReader.getClassMetadata();
		System.out.println(classMetadata.getClassName());
		// 获取一个AnnotationMetadata，并获取类上的注解信息
		AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
		for (String annotationType : annotationMetadata.getAnnotationTypes()) {
			System.out.println(annotationType);
		}
		//直接注解
		System.out.println(annotationMetadata.hasAnnotation(Component.class.getName()));
		//注解的注解
		System.out.println(annotationMetadata.hasMetaAnnotation(Component.class.getName()));*/

		/**
		 * ExcludeFilter IncludeFilter 配置了 includeFilter的类,不配置Component也是可以被认为是一个bean的
		 */
		/*
		@ComponentScan(value = "com.zhouyu",
		excludeFilters = {@ComponentScan.Filter(
            	type = FilterType.ASSIGNABLE_TYPE,
            	classes = UserService.class)}.)
		public class AppConfig {
		}

		@ComponentScan(value = "com.zhouyu",
				includeFilters = {@ComponentScan.Filter(
						type = FilterType.ASSIGNABLE_TYPE,
						classes = UserService.class)})
		public class AppConfig {
		}

//		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
//		System.out.println(context.getBean("userService"));*/

		/**
		 * FactoryBean
		 *
		 * factoryBean是经历过完整的生命周期的
		 * factoryBean里面的bean没有经过完整的生命周期，在这里也就是 userService ，只会经过初始化后这一步骤
		 *
		 * 初始化前:com.zhouyu.service.ZhouyuFactoryBean@35083305
		 * 初始化后:com.zhouyu.service.ZhouyuFactoryBean@35083305
		 * 初始化后:com.zhouyu.service.UserService@11dc3715
		 * com.zhouyu.service.UserService@11dc3715
		 */
		/*AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
		System.out.println(context.getBean("userService"));
//		System.out.println(context.getBean("&&zhouyuFactoryBean"));*/
	}
}
